#coding=utf-8
'''
Created on 2017-04-20

@author: sandy
'''
import os
import platform
import re
import random
import time
import hashlib
import json
import Const
import math
import uuid

PASSWD_HASH_KEY = "085125e8f7cdc99f"
MPHONE_LEN = 11

def pstr2u(pstr):
    return pstr.decode(Const.PROTOCOL_STR_ENCODING)

def u2pstr(ustr):
    return ustr.encode(Const.PROTOCOL_STR_ENCODING)

def isValidAccount(account):
    al = len(account)
    if al<Const.ACCOUNT_LEN_MIN or al>Const.ACCOUNT_LEN_MAX:
        return False
    for c in account:
        n = ord(c)
        if n>= ord('0') and n<=ord('9'):
            continue
        if n>=ord('a') and n<=ord('z'):
            continue
        if n>=ord('A') and n<=ord('Z'):
            continue
        return False
    return True  

def isValidAccountInternal(account):
    al = len(account)
    if al<Const.ACCOUNT_LEN_MIN or al>Const.ACCOUNT_LEN_MAX:
        return False
    i = 0
    for c in account:
        i += 1
        n = ord(c)
        if n>= ord('0') and n<=ord('9'):
            continue
        if n>=ord('a') and n<=ord('z'):
            continue
        if n>=ord('A') and n<=ord('Z'):
            continue
        if c==u'-':
            continue
        return False
    return True

def isNamespaceAccount(account):
    if not isValidAccountInternal(account):
        return False
    if account.find(u'-')==-1:
        return False
    return True

def isValidNormalAccount(account):
    if not isValidAccount(account):
        return False
    allnum = True
    for c in account:
        n = ord(c)
        if not (n>= ord('0') and n<=ord('9')):
            allnum = False
            break
    if allnum and len(account)==MPHONE_LEN:
        return False
    return True    

def isAvalidMPhoneAccount(account):    
    return isValidMPhone(account)
    
def isValidNickname(nickname):
    nl = len(nickname)
    if nl<Const.NICKNAME_LEN_MIN or nl>Const.NICKNAME_LEN_MAX:
        return False
    if nickname.find(u" ")>=0:
        return False
    return True

def isValidPasswd(passwd):
    pl = len(passwd)
    if pl<Const.PASSWD_LEN_MIN or pl>Const.PASSWD_LEN_MAX:
        return False
    return True

def isValidDeviceId(deviceid):
    dl = len(deviceid)
    if dl<Const.DEVICEID_LEN_MIN or dl>Const.DEVICEID_LEN_MAX:
        return False
    return True

def isValidSex(sex):
    if sex<0 or sex>2:
        return False
    return True

EMAIL_RULE = r"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
def isValidEmail(email):
    if len(email)>60:
        return False
    return re.match(EMAIL_RULE, email)!=None

def isValidPhoto(photo):
    return photo>=0 and photo<=100

def isValidIdcard(idcard):
    if len(idcard)!=18:
        return False
    for c in idcard:
        n = ord(c)
        if not (n>= ord('0') and n<=ord('9')):
            return False  
    return True  

MP_HEADER = [130,131,132,133,134,135,136,137,138,139,145,147,150,151,152,153,155,156,157,158,159,170,177,178,180,181,182,183,184,185,186,187,188,189]
def isValidMPhone(mphone):
    if len(mphone)!=MPHONE_LEN:
        return False
    for c in mphone:
        n = ord(c)
        if not (n>= ord('0') and n<=ord('9')):
            return False
    header = int(mphone[:3])
    if not header in MP_HEADER:
        return False
    return True    

def ecode2str(ecode):
    return u''

def ecode2pstr(ecode):
    return ''

def passwdHash(account, passwd):
    s = str(len(passwd)*len(account)) + passwd.encode("utf-8") + PASSWD_HASH_KEY + account.encode("utf-8")
    return hashlib.md5(s).hexdigest()

def genSession():
    return random.randint(1000, 10000) * random.randint(10000, 100000)


ISOTIMEFORMAT = u'%Y-%m-%d %X'
def getTimeNowString():
    return unicode(time.strftime(ISOTIMEFORMAT, time.localtime()))

def getTimeString(t):
    return unicode(time.strftime(ISOTIMEFORMAT, time.localtime(t)))

def timeString2timestamp(ts):
    return time.mktime(time.strptime(ts,ISOTIMEFORMAT))

FILL91 = u"abcdefabcdefabcdefabcdefabcdefab"
def make91OrderString(orderid):
    s = unicode(orderid)
    s += FILL91[len(s):]
    return s

def extract91OrderId(orderid):
    index = 0
    for c in orderid:
        if not c.isdigit():
            break
        index += 1
    return int(orderid[:index])

FILLZF = u"abcdefabcd"
def makeZFOrderString(orderid):
    s = unicode(orderid)
    s += FILLZF[len(s):]
    return s

def extractZFOrderId(orderid):
    index = 0
    for c in orderid:
        if not c.isdigit():
            break
        index += 1
    return int(orderid[:index])

def rc4crypt(data, key):
    x = 0
    box = range(256)
    for i in range(256):
        x = (x + box[i] + ord(key[i % len(key)])) % 256
        box[i], box[x] = box[x], box[i]
    x = 0
    y = 0
    out = []
    for char in data:
        x = (x + 1) % 256
        y = (y + box[x]) % 256
        box[x], box[y] = box[y], box[x]
        out.append(chr(ord(char) ^ box[(box[x] + box[y]) % 256]))
    
    return ''.join(out) 

def md5sumhex(data):
    m = hashlib.md5()
    m.update(data)
    return m.hexdigest()

def md5file(path):
    with open(path, 'rb') as f:
        data = f.read()
        m = hashlib.md5()
        m.update(data)
        return m.hexdigest()

def xmlget(root, k):
    if len(root.getElementsByTagName(k)[0].childNodes)==0:
        return u''
    return root.getElementsByTagName(k)[0].childNodes[0].data

def loadDaemonConfig(rundir):
    cf = json.load(file(os.path.join(rundir,u'daemon.json')), encoding='utf-8')
    sid = cf.get(u'server_id')
    logfile = cf.get(u'log_file')
    #if platform.system() == "Linux" and logfile[0]!="/":
    #    logfile = u"/var/log/"+logfile  
    loglevel = cf.get(u'log_level')        
    msip = cf.get(u'manager_server_ip')
    msport = cf.get(u'manager_server_port')
    pidpath = u'/tmp/%s_%d_%d' % (msip, msport, sid)
    pathSelfConfig = cf.get(u'pathSelfConfig', None)#D:\\svn\\Server\\managersrv\\server401
    print sid, msip, msport, pidpath, logfile, loglevel, pathSelfConfig
    return sid, msip, msport, pidpath, logfile, loglevel, pathSelfConfig

    
DBKEY = 'qmREqhcJyZ2IC7sjPNDdFrajZWhu7d'
def encryptDbStr(str):
    return rc4crypt(str.encode('UTF-8'), DBKEY).encode('base64')

def dencryptDbStr(str):
    return rc4crypt(str.decode('base64'), DBKEY).decode('UTF-8')

def getPropAttributeType(pid):
    return int(str(pid)[0:1])

def getStamp_Y_M_D(diff=0):
    '''
    date = time.strftime("%Y-%m-%d", time.localtime(int(time.time())))
    timeArray = time.strptime(date, "%Y-%m-%d")
    timeStamp = int(time.mktime(timeArray)) + diff'''
    timeStamp = int(time.time()) + diff
    return timeStamp

def cmpStamp_Y_M_D(stampA, stampB):
    ymdA = stampA / 86400
    ymdB = stampB / 86400
    if ymdA > ymdB:
        return -1
    if ymdA == ymdB:
        return 0
    return 1

def genExternalSession(uid, session):
    return md5sumhex(str(uid)+"USERSESSION"+str(session))

def genAutoRegPasswd():
    s = unicode(uuid.uuid4())
    return s[-12:]

def parseValueItems(vstr):
    ret = []
    if len(vstr)==0:
        return ret
    strs = vstr.split(u',')
    for vs in strs:
        item = vs.split(u'|')
        ret.append(item)
    return ret
    
if __name__ == '__main__':
    pass